<?php

namespace StudyBuddy;

/**
 * Class represents a Comment submitted via Browser
 * has methods to get body, ip, parent Resource and other
 * properties of the comment
 */
class SubmittedCommentWWW implements \StudyBuddy\Interfaces\SubmittedComment {
    /**
     * The one comment is a resource
     * of type COMMENT
     * This identifying string is stored
     * in RESOURCE collection
     *
     * @var string
     */
    const RESOURCE_TYPE = 'COMMENT';

    /**
     * Registry Object
     *
     * @var object of type Registry
     */
    protected $oRegistry;

    /**
     * ID of ANSWER or QUESTIONS resource
     * (NOT COMMENT RESOURCE)
     *
     *
     * @var int
     */
    protected $resourceID;

    /**
     *
     * Resource for which this comment
     * is made
     * @var object either Question or Answer
     */
    protected $oResource;

    /**
     * Name of Mongo Collection where
     * this comment will be stored
     * It's either QUESTIONS or ANSWERS
     * depending on type of $oResource
     *
     * @var string
     */
    protected $collection;

    /**
     * Constructor
     *
     * @param object \StudyBuddy\Registry $oRegistry
     * @param object \StudyBuddy\Interfaces\StudyBuddyResource $oResource
     */
    public function __construct(\StudyBuddy\Registry $oRegistry, \StudyBuddy\Interfaces\StudyBuddyResource $oResource = null) {
        $this->oRegistry = $oRegistry;
        if ($oResource) {
            $this->setResource($oResource);
            $this->getResourceCollection();
        }
    }

    /**
     * Set the value of $this->oResource
     * and also the value of $this->collection
     *
     * @param \StudyBuddy\Interfaces\StudyBuddyResource $oResource
     */
    public function setResource(\StudyBuddy\Interfaces\StudyBuddyResource $oResource = null) {
        if (null !== $oResource) {
            $this->oResource = $oResource;
            $this->getResourceCollection();
        } else {
            $this->findCollection();
            $this->initResource();
        }
    }

    protected function getResourceCollection() {

        if (!isset($this->collection)) {
            $this->getResource();

            if ($this->oResource instanceof \StudyBuddy\Answer) {
                $this->collection = 'ANSWERS';
            } else {
                $this->collection = 'QUESTIONS';
            }
        }

        return $this->collection;
    }

    protected function findCollection() {

        $commentID = $this->oRegistry->Request->get('commentid', 'i', 0);
        if (0 !== $commentID) {
            $this->getCollectionByCommentId($commentID);
        } else {
            $this->findCollectionByResourceId($this->oRegistry->Request['rid']);
        }

        return $this;
    }

    /**
     * Create object of type Question or Answer
     *
     * @return object $this
     */
    protected function initResource() {

        $coll = $this->oRegistry->Mongo->getCollection($this->collection);
        $a = $coll->findOne(array('_id' => $this->resourceID));
        d('a: ' . print_r($a, 1));

        if (empty($a)) {

            throw new \StudyBuddy\Exception('Item not found');
        }

        $class = ('QUESTIONS' === $this->collection) ? '\\StudyBuddy\\Question' : '\\StudyBuddy\\Answer';

        $this->oResource = new $class($this->oRegistry, $a);


        return $this;
    }

    /**
     * Find name of the collection
     * this comment will belong to
     *
     * @param int $resID id of question or answer
     * @throws \StudyBuddy\Exception
     *
     * @return object $this
     */
    protected function findCollectionByResourceId($resID) {
        $a = $this->oRegistry->Mongo->RESOURCE->findOne(array('_id' => $resID));
        d('a: ' . print_r($a, 1));
        if (empty($a)) {
            throw new \StudyBuddy\Exception('RESOURCE NOT FOUND by id ' . $resID);
        }

        if (!empty($a['res_type']) && ('ANSWER' === $a['res_type'] )) {
            $this->collection = 'ANSWERS';
        } else {
            $this->collection = 'QUESTIONS';
        }

        $this->resourceID = $resID;

        return $this;
    }

    /**
     * Get object of type User of user
     * who posted the answer
     *
     * @return object of type User
     */
    public function getUserObject() {

        return $this->oRegistry->Viewer;
    }

    /**
     * @return object of type Utf8String
     */
    public function getBody() {

        $body = $this->oRegistry->Request->getUTF8('com_body')->htmlentities()->mmd2Html()->wordWrap(70, "\n", true);
        d('$body: ' . $body);

        return $body;
    }

    /**
     * @return string ip address from where
     *
     * the answer was submitted
     */
    public function getIP() {

        return Request::getIP();
    }

    /**
     * @return int id of question for which
     * this comment is submitted
     */
    public function getQuestionId() {
        if (!$this->oResource) {
            $this->setResource();
        }

        if ($this->oResource instanceof \StudyBuddy\Question) {
            $ret = $this->oResource->getResourceId();
        } elseif ($this->oResource instanceof \StudyBuddy\Answer) {
            $ret = $this->oResource['i_qid'];
        } else {
            throw new DevException('Resource is not Question and Not Answer ' . get_class($this->oResource));
        }

        if (empty($ret)) {
            throw new DevException('Something is Wrong: QuestionID cannot is empty');
        }

        return (int) $ret;
    }

    /**
     *
     * Get parent id - the id of
     * comment for which this is a reply
     *
     * @return int 0 means no parent
     */
    public function getParentId() {

        return $this->oRegistry->Request->get('parentid', 'i', 0);
    }

    /**
     * Get GeoIP data
     *
     * @return associative array
     */
    public function getExtraData() {
        return $this->oRegistry->Geo->Location->data;
    }

    /**
     * Returns type of resource
     * the type of resource is a string stored in RESOURCE
     * collection as res_type
     *
     * @return string
     */
    public function getResourceTypeId() {

        return self::RESOURCE_TYPE;
    }

    /**
     * Returnes id of user (USERS.id)
     * who owns the resource
     * Which is usually the user who created it
     * but doest not have to be.
     * It is up to the individual class
     * to decide who owns the resource.
     *
     * @return int
     */
    public function getOwnerId() {

        return $this->getUserObject()->getUid();
    }

    /**
     * Get unix timestamp of
     * when resource was last modified
     * This includes any type of change made to a
     *
     * resource, including when new comments were added
     * or new rating added ,etc.
     *
     * It's up to the implementer to decide what changes
     * are significant enough to be considered modified
     * but usually the on update CURRENT TIMESTAMP
     * is a very good way to mark resouce as modified
     *
     * @return int last modified time in unix timestamp
     *
     */
    public function getLastModified() {

        return time();
    }

    /**
     * Every resource when deleted actually has
     * a 'deleted' timestamp set
     * to the time when it was deleted.
     * This way we consider a resource as deleted
     * but can also find and possibly show
     * the date/time when resource was deleted
     * and also have the option to 'undelete'
     * by just switching the 'deleted' column value
     * back to 0
     *
     * @return int
     * 0 means not deleted or unix timestamp of when resource
     * was marked as deleted
     */
    public function getDeletedTime() {

        return 0;
    }

    /**
     * Updates last modified timestamp
     *
     */
    public function touch() {
        
    }

    protected function getCollectionByCommentId($commentid) {
        $a = $this->oRegistry->Mongo->COMMENTS->findOne(array('_id' => $commentid));
        d('a: ' . print_r($a, 1));
        if (empty($a) || empty($a['coll'])) {
            throw new \StudyBuddy\Exception('RESOURCE NOT FOUND by id ' . $commentid);
        }

        $this->collection = $a['coll'];
        $this->resourceID = $a['i_res'];

        return $this;
    }

    /**
     * In case of edit, the comment id is passed
     * in the form as the 'rid' value
     * otherwise we don't have the id yet if this is a new
     * comment being submitted and we
     * generate one right now.
     *
     * (non-PHPdoc)
     * @see StudyBuddy\Interfaces.Resource::getResourceId()
     */
    public function getResourceId() {

        $id = $this->oRegistry->Request->get('commentid', 'i', 0);
        if (!empty($id)) {
            d('got commentid: ' . $id);

            return $id;
        }

        return $this->oRegistry->Resource->create(self::RESOURCE_TYPE);
    }

    public function getResource() {
        if (!$this->oResource) {
            d('resource not yet set... setting one now');
            $this->setResource();
        }

        return $this->oResource;
    }

    public function getCollectionName() {

        return $this->getResourceCollection();
    }

    /**
     * Get name of app used for submitting
     * this question
     * @return string
     */
    public function getApp() {
        return 'web';
    }

    /**
     * Get id of app used for submitting
     * this question
     * @return null
     */
    public function getAppId() {
        return null;
    }

    /**
     * Get id of link to app used for submitting
     * this question
     *
     * @return null
     */
    public function getAppLink() {
        $name = $this->getApp();
        $id = $this->getAppId();

        return (!empty($id) && !empty($name)) ? \sprintf('<a href="/app/%s" rel="nofollow" target="_blank">%s</a>', $id, $name) : null;
    }

}
